package org.zcl.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.zcl.entity.response.ChannelResponse;
import org.zcl.enums.StrategyEnum;
import org.zcl.service.PayService;
import org.zcl.service.SinglePayService;
import org.zcl.service.convert.ChannelPayConverter;
import org.zcl.service.factory.ChannelServiceFactory;
import org.zcl.service.impl.QueryTypeService;
import org.zcl.utils.QueryService;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Package org.zcl.controller
 * @PROJECT_NAME: question
 * @DESCRIPTION:
 * @USER: zhuchenglin
 * @DATE: 2021/12/3 13:50
 */
@RestController
@Slf4j
@Api(value = "策略模式+线程调用测试", tags = "QueryController")
public class QueryController {

    @Autowired
    private QueryTypeService queryTypeService;

    @GetMapping("query")
    @ApiOperation(value = "query", notes = "获取不同策略的结果(方法包装成类获取方式)")
    public List<String> query(@ApiParam(name = "type", required = true) @RequestParam(value = "type") Integer type) throws Exception {
        log.info("类型type:{}", type);
        QueryService queryService = StrategyEnum.getAdapter(type);
        return queryService.query();
    }

    @GetMapping("queryType")
    @ApiOperation(value = "queryType", notes = "获取不同策略的结果(map函数式接口方式)")
    public List<String> queryType(@ApiParam(name = "type", required = true) @RequestParam(value = "type") String type) throws Exception {
        log.info("类型type:{}", type);
        QueryService queryService = queryTypeService.getResult(type);
        return queryService.query();
    }

    @Autowired
    private List<SinglePayService> singlePayServices;

    @GetMapping("doPay")
    @ApiOperation(value = "doPay", notes = "获取不同策略的结果(通过注解接口方式)")
    public boolean doPay(String code) {
        List<SinglePayService> services = singlePayServices.stream()
                .filter(singlePayService -> singlePayService.support(code))
                .sorted(Comparator.comparingInt(Ordered::getOrder))
                .collect(Collectors.toList());
        for (SinglePayService service : services) {
            service.doPay();
        }
        return true;
    }

    @Autowired
    private ChannelServiceFactory factory;

    @GetMapping("applyPay")
    @ApiOperation(value = "applyPay", notes = "获取不同策略(枚举map)，根据工厂获取bean,再调用实现类的方法")
    public ChannelResponse applyPay(String code) {
        ChannelPayConverter payConverter = factory.getPayConverter(code);
        Object convert = payConverter.convert();
        PayService payService = factory.getPayService(code);
        return (ChannelResponse<?>) payService.applyPay(convert);
    }
}
